package activiti

import com.fasterxml.jackson.databind.JsonNode
import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.databind.node.ObjectNode
import grails.converters.JSON
import org.activiti.bpmn.converter.BpmnXMLConverter
import org.activiti.bpmn.model.BpmnModel
import org.activiti.editor.language.json.converter.BpmnJsonConverter
import org.activiti.engine.ActivitiException
import org.activiti.engine.ProcessEngine
import org.activiti.engine.ProcessEngines
import org.activiti.engine.RepositoryService
import org.activiti.engine.repository.Model
import org.activiti.engine.runtime.ProcessInstance
import org.apache.commons.io.IOUtils
import org.apache.commons.lang.StringUtils

class ActivitController {
    ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine()

    RepositoryService repositoryService = processEngine.getRepositoryService()

    ObjectMapper objectMapper = new ObjectMapper()
    def utilsService
    def activitService

    /**根据Id获取创建的模板信息*/

    def getEditorJson() {
        log.debug("-----" + params)
        def record = request.JSON ?: params

        ObjectNode modelNode = null

        Model model = repositoryService.getModel(record.id?.toString() ?: '')

        if (model != null) {

            try {

                if (StringUtils.isNotEmpty(model.getMetaInfo())) {

                    modelNode = (ObjectNode) objectMapper.readTree(model.getMetaInfo())

                } else {

                    modelNode = objectMapper.createObjectNode()

                    modelNode.put("name", model.getName())

                }

                modelNode.put("modelId", model.getId())
                modelNode.put("key", model.getKey())

                ObjectNode editorJsonNode = (ObjectNode) objectMapper.readTree(new String(repositoryService.getModelEditorSource(model.getId()), "utf-8"))

                modelNode.put("model", editorJsonNode)


            } catch (Exception e) {

                throw new ActivitiException("Error creating model JSON", e)

            }

        }
        render modelNode

    }

    /**保存修改的模型*/

    def saveModel() {
        log.debug(params)
        activitService.saveModel(params)
        render true
    }

    def getStencilset() {

        InputStream stencilsetStream = this.getClass().getClassLoader().getResourceAsStream("stencilset.json")

        try {

            render IOUtils.toString(stencilsetStream, "utf-8")

        } catch (Exception e) {

            throw new ActivitiException("Error while loading stencil set", e)

        }

    }

    /** 新建一个空模型 */
//http://localhost:9016/activiti6/activit/newModel?name=test&key=test&description=testModel
    def newModel() {
        params.request = request
        def result = activitService.newModel(params)
        if (params.RETURNJSON) {
            render result as JSON

        } else
            render result.modelId

    }

    /** 获取所有模型 */

    def modelList() {

        RepositoryService repositoryService = processEngine.getRepositoryService()

        render repositoryService.createModelQuery().list() as JSON

    }
    /** 获取已发布的列表   */
    //    http://localhost:9016/activiti6/activit/deployList
    def deployList() {
        RepositoryService repositoryService = processEngine.getRepositoryService()
        def list = repositoryService.createDeploymentQuery().list()
        render list
    }

    /** 发布模型为流程定义 */
//    http://localhost:9016/activiti6/activit/deploy?id=1
    def deploy() {
        params.request = request
        render activitService.deploy(params)

    }

    /**启动流程*/
//    http://localhost:9016/activiti6/activit/startProcess?keyName=fangProcess
    def startProcess() {

        def record = request.JSON ?: params

        ProcessInstance process = processEngine.getRuntimeService().startProcessInstanceByKey(record.keyName)

        render process.getId() + " : " + process.getProcessDefinitionId()

    }
//  http://localhost:8010/prm/activit/getModelXml?id=10159
    def getModelXml() {
        log.debug(params)
        def record = request.JSON ?: params
        //获取模型
        Model modelData = repositoryService.getModel(record.id)
        if (!modelData) {
            render "异常数据,请删除后重新创建流程"
            return
        }
        byte[] bytes = repositoryService.getModelEditorSource(modelData?.getId())
        if (bytes == null) {
            render "模型数据为空，请先设计流程并成功保存，再进行查看Xml"
            return
        }
        JsonNode modelNode = new ObjectMapper().readTree(bytes)
        BpmnModel model = new BpmnJsonConverter().convertToBpmnModel(modelNode)
        if (model.getProcesses().size() == 0) {
            render "数据模型不符要求，请至少设计一条主线流程"
        } else {
            byte[] xmlbytes = new BpmnXMLConverter().convertToXML(model)
            def ouputStream = response.getOutputStream();
//            response.setContentType("application/xhtml+xml");//("application/vnd.ms-excel");
            response.setContentType("text/plain");//("application/vnd.ms-excel");
            response.setContentLength(xmlbytes.length);
            ouputStream.write(xmlbytes, 0, xmlbytes.length);
            ouputStream.flush();
            ouputStream.close();
        }
    }
    //  http://localhost:8010/prm/activit/getModelPic?id=10159
    def getModelPic() {
        log.debug(params)
        def record = request.JSON ?: params
        byte[] bytes = repositoryService.getModelEditorSourceExtra(record.id)
        if (bytes == null) {
            render "模型数据为空，请先设计流程并成功保存，再进行查看流程图片"
            return
        }
        def ouputStream = response.getOutputStream();
        response.setContentType("image/jpeg");//("application/vnd.ms-excel");
        response.setContentLength(bytes.length);
        ouputStream.write(bytes, 0, bytes.length);
        ouputStream.flush();
        ouputStream.close();
    }

    //  删除模型
    def delModel() {
        log.debug(params)
        def result = activitService.delModel(params)
        render result as JSON
    }
    //  http://localhost:8010/prm/activit/getTasksFromModel?id=15011
//    def getTasksFromModel() {
//        def result=activitService.getTasksFromModel(params)
//        render result as JSON
//    }
//    http://localhost:8010/prm/activit/testimp
    def testimp(){
        activitService.impnewModel()
    }

    def imp(){
        def f = request.getFile('attachment')
        def categoryImportedCnt = 0
        def outArr = []
        def message = ""
        if (!f.empty) {
            activitService.impnewModel(f.inputStream)
        }
        render contentType: "text/html", text: ([success: true,importedCnt:1] as JSON)
    }
}
